function WebAppController(){
	
	this.view = {extend: "base" };
	
	this.handler = function(){
		
		var user = request.getAttr("user");
		
		if(!user){
			request.setAttr("loginRedirect", request.uri);
			request.forward("login");
		}
		
		var htmlForm = new HTMLForm.generator(request);
		
		var addServiceForm = htmlForm.create({
			id: "addServiceForm",
			method: "post",
			inputs: [
				{"feedUrl": {label: "feed url:", validate: {required: true, url: true}}},
				{"submit_": {value: "submit", type: "submit"}}
			]
		});
		
		this.get = function(showErrors, errorMsg){
			if(errorMsg)
				$("#content").append("<p class='error'>" + errorMsg + "</p>");
			$("#content").append(addServiceForm.html(showErrors));
		}
		
		this.post = function(){
			var errorMsg;
			if(addServiceForm.pass){
				var feedResponse, url = $.trim(addServiceForm.values.feedUrl).toLowerCase();
				$.ajax({
					url: url,
					async: false,
					complete: function(xhr){
						feedResponse = xhr;
					}
				});
				
				var guid = (new GUID.generator()).generate();
				if(feedResponse.responseXML.documentElement.tagName == "rss"){
					var service = db.services.getSingle({creator: user.username, feedUrl: url});
					if(!service){
					
						db.services.insert({
							type: "entry",
							verb: "post",
							guid: guid,
							creator: user.username,
							name: $("rss > channel > title", feedResponse.responseXML).text(),
							link: $("rss > channel > link", feedResponse.responseXML).text(),
							description: $("rss > description, rss > channel > description", feedResponse.responseXML).text(),
							feedUrl: url
						});
						
						user.services.push(guid);
						db.users.update(user, {username: user.username});
						
						$("item", feedResponse.responseXML).each(function(i, feedItem){
							var link = $("link", feedItem).text(), item = db.feedItems.getSingle({link: link, feedUrl: url});
							
							if(!item){
								
								var addDate = new Date(), pubDate = $("pubDate, pubdate", feedItem).text(), feedItemPubDate = new Date(pubDate);
								if(feedItemPubDate.toString() === "Invalid Date"){
									feedItemPubDate = Date.parseExact(pubDate, "ddd, dd MMM yyyy HH:mm:ss GMT") || addDate;
								}
								while(feedItemPubDate.isAfter(new Date())){
									feedItemPubDate.addHours(-1);
								}
								db.feedItems.insert({
									feedUrl: url,
									guids: [guid],
									link: link,
									title: $("title", feedItem).text(),
									description: "<![CDATA[" + $("description", feedItem).text() + "]]>",
									pubDate: feedItemPubDate,
									addDate: addDate
								});
								
							} else {
								item.value.guids.push(guid);
								db.feedItems.update(item.value, {link: link, feedUrl: url});
							}
						});
					}
					response.redirect("/ashafa/service/" +  ((service) ? service.value.guid : guid));
						
				} else {
					addServiceForm.addError("feedurl", "'feedurl' is not a feed.");
				}
				
			}
			this.get(!addServiceForm.pass, errorMsg);
		}
	}

}